<template>
    <view class="page-wrap">
        <map
            id="map"
            class="map"
            show-location
            :longitude="longitude"
            :latitude="latitude"
            @regionchange="handleRegionChange"
        >
            <cover-image class="back-button" src="/static/utils/icon_back_3x.png" @tap.stop="handleBack" />
            <cover-image class="location-marker" :class="{ 'location-marker--beat': ani }" src="/static/utils/icon_marker_3x.png" />
            <cover-image class="location-button" src="/static/utils/icon_location_3x.png" @tap.stop="handleClickLocation"></cover-image>
        </map>
        <view class="search-wrap">
            <u-search
                placeholder="小区/写字楼/学校等"
                v-model="searchKeywords"
                animation
                @change="$refs['list'].refresh()"
                @clear="$refs['list'].refresh()"
                @custom="$refs['list'].refresh()"
                @search="$refs['list'].refresh()"
            ></u-search>
        </view>
        <view class="address-list">
            <scroll-list ref="list" :option="option" @load="load" @refresh="refresh">
                <view class="address-item" hover-class="address-item--active" v-for="(item, index) in aroundPOI" :key="index" @click="handleSelectAddress(item)">
                    <view class="icon-wrap"><u-icon name="map" :color="themeColor" size="32"></u-icon></view>
                    <view class="address-info">
                        <text class="address-name">{{ item.title }}</text>
                        <view class="address-info-bottom">
                            <view class="distance-text">{{ item.distance | getDistance(item._distance) }}</view>
                            <text class="address-text">{{ item.address }}</text>
                        </view>
                    </view>
                </view>
            </scroll-list>
        </view>
    </view>
</template>

<script>
const QQMapWX = require('@/libs/sdk/qqmap-wx-jssdk.min.js');
export default {
    data() {
        return {
            keywords: '', // POI关键词
            searchKeywords: '', // 搜索POI关键词
            aroundPOI: [], // 周围POI
            isMove: false,
            ani: true,
            mapCtx: null,
            mapObj: null,
            longitude: 114.010857, // 经度
            latitude: 22.63137, // 纬度
            key: 'QJKBZ-OWMCF-WTVJR-ND5JP-VYOWH-HYBTD',
            qqmapsdk: null,
            timer: null,
            isClick: false, //选择地址防止app端刷新地址
            option: {
                auto: false,
                size: 10,
                emptyImage: '/static/occupy/zwdz.png'
            },
            eventName: 'address' // 监听事件名称
        };
    },
    methods: {
        // 初始化
        handleInit(option) {
            if (option.eventName) this.eventName = option.eventName;
            this.keywords = option.keywords || '';
            this.qqmapsdk = new QQMapWX({ key: this.key });
            this.handleGetCurrentLocation();
        },
        // 点击获取当前位置
        handleClickLocation() {
            if (this.isMove) {
                this.handleGetCurrentLocation();
                this.isMove = false;
            }
        },
        // 获取当前位置经纬度
        handleGetCurrentLocation() {
            uni.getLocation({
                // #ifdef APP-PLUS || MP-WEIXIN
                type: 'gcj02',
                // #endif
                success: res => {
                    this.latitude = res.latitude;
                    this.longitude = res.longitude;
                    this.handleGeocoder(res.latitude, res.longitude);
                    this.mapCtx && this.mapCtx.moveToLocation();
                },
                fail: err => {
                    console.log(err);
                    this.handleGeocoder();
                    this.mapCtx && this.mapCtx.moveToLocation();
                }
            });
        },
        // 计算距离
        handleComputeDistance(to, callback = () => {}) {
            // #ifdef H5
            let toStr = '';
            to.forEach((item, index) => {
                if (item.location.lat && item.location.lng) {
                    toStr = index == 0 ? toStr + `${item.location.lat},${item.location.lng}` : toStr + `;${item.location.lat},${item.location.lng}`;
                }
            });
            this.$request
                .jsonp('https://apis.map.qq.com/ws/distance/v1/', {
                    key: this.key,
                    to: toStr,
                    from: `${this.latitude},${this.longitude}`,
                    mode: 'driving',
                    output: 'jsonp',
                    callback: 'QQmap'
                })
                .then(res => {
                    if (res.status === 0) {
                        callback(res.result);
                    } else {
                        callback(false);
                    }
                });
            // #endif
            // #ifndef H5
            this.qqmapsdk.calculateDistance({
                from: `${this.latitude},${this.longitude}`,
                to: to,
                success: res => {
                    callback(res.result);
                },
                fail: res => {
                    callback(false);
                }
            });
            // #endif
        },
        // 地址解析
        handleGeocoder(latitude, longitude, refresh = false) {
            // #ifdef H5
            this.$request
                .jsonp('https://apis.map.qq.com/ws/geocoder/v1/', {
                    key: this.key,
                    get_poi: 0,
                    output: 'jsonp',
                    callback: 'QQmap',
                    location: `${latitude},${longitude}`
                })
                .then(res => {
                    if (res.status === 0) {
                        this.keywords = res.result.formatted_addresses.recommend;
                        if (refresh) {
                            this.aroundPOI = [];
                            this.$refs['list'].refresh();
                        } else {
                            this.$refs['list'].load();
                        }
                    }
                });
            // #endif
            // #ifndef H5
            //根据经纬度获取地址信息
            this.qqmapsdk.reverseGeocoder({
                location: `${latitude},${longitude}`,
                success: res => {
                    this.keywords = res.result.formatted_addresses.recommend;
                    if (refresh) {
                        this.aroundPOI = [];
                        this.$refs['list'].refresh();
                    } else {
                        this.$refs['list'].load();
                    }
                },
                fail: res => {
                    if (refresh) {
                        this.aroundPOI = [];
                        this.$refs['list'].refresh();
                    } else {
                        this.$refs['list'].load();
                    }
                }
            });
            // #endif
        },
        // 位置信息改变
        handleRegionChange(e) {
            this.searchKeywords = '';
            let isEnd = e.type == 'end';
            // #ifdef APP-PLUS || MP-WEIXIN
            isEnd = e.type == 'end' && (e.causedBy == 'scale' || e.causedBy == 'drag');
            // #endif
            if (isEnd) {
                this.isMove = true;
                clearTimeout(this.timer);
                this.ani = false;
                this.timer = setTimeout(() => {
                    this.ani = true;
                }, 300);
                if (!this.mapCtx) {
                    this.mapCtx = uni.createMapContext('map');
                }
                this.mapCtx.getCenterLocation({
                    type: 'gcj02',
                    success: res => {
                        this.latitude = res.latitude;
                        this.longitude = res.longitude;
                        this.handleGeocoder(res.latitude, res.longitude, true);
                    },
                    fail: err => {
                        console.log(err);
                    }
                });
            }
        },
        // 加载周围POI数据
        load(paging) {
            // #ifdef H5
            // H5端用jsonp请求数据
            this.$request
                .jsonp('https://apis.map.qq.com/ws/place/v1/suggestion', {
                    key: this.key,
                    keyword: this.searchKeywords || this.keywords,
                    output: 'jsonp',
                    callback: 'QQmap',
                    get_subpois: 1,
                    policy: 1,
                    region_fix: 1,
                    location: `${this.latitude},${this.longitude}`,
                    page_size: paging.size,
                    page_index: paging.page
                })
                .then(res => {
                    if (res.status === 0) {
                        let list = res.data || [];
                        this.handleComputeDistance(list, result => {
                            if (result && result.elements.length) {
                                result.elements.forEach((item, index) => {
                                    list[index].distance = item.distance;
                                });
                            }
                            this.aroundPOI = [...this.aroundPOI, ...list];
                            this.$refs.list.loadSuccess({ list: this.aroundPOI, total: res.count });
                        });
                    } else {
                        uni.showToast({
                            icon: 'error',
                            title: res.message
                        });
                        this.$refs.list.refreshFail();
                    }
                });
            // #endif
            // #ifndef H5
            this.qqmapsdk.getSuggestion({
                keyword: this.searchKeywords || this.keywords,
                page_size: paging.size,
                page_index: paging.page,
                location: `${this.latitude},${this.longitude}`,
                success: res => {
                    if (res.status === 0) {
                        let list = res.data || [];
                        this.handleComputeDistance(list, result => {
                            if (result && result.elements.length) {
                                result.elements.forEach((item, index) => {
                                    list[index].distance = item.distance;
                                });
                            }
                            this.aroundPOI = [...this.aroundPOI, ...list];
                            this.$refs.list.loadSuccess({ list: this.aroundPOI, total: res.count });
                        });
                    } else {
                        uni.showToast({
                            icon: 'error',
                            title: res.message
                        });
                        this.$refs.list.refreshFail();
                    }
                },
                fail: res => {
                    uni.showToast({
                        icon: 'error',
                        title: res.message
                    });
                    this.$refs.list.refreshFail();
                }
            });
            // #endif
        },
        // 刷新周围POI数据
        refresh(paging) {
            // #ifdef H5
            // H5端用jsonp请求数据
            this.$request
                .jsonp('https://apis.map.qq.com/ws/place/v1/suggestion', {
                    key: this.key,
                    keyword: this.searchKeywords || this.keywords,
                    output: 'jsonp',
                    callback: 'QQmap',
                    get_subpois: 1,
                    policy: 1,
                    region_fix: 1,
                    location: `${this.latitude},${this.longitude}`,
                    page_size: paging.size,
                    page_index: paging.page
                })
                .then(res => {
                    if (res.status === 0) {
                        let list = res.data || [];
                        this.handleComputeDistance(list, result => {
                            if (result && result.elements.length) {
                                result.elements.forEach((item, index) => {
                                    list[index].distance = item.distance;
                                });
                            }
                            this.aroundPOI = list;
                            this.$refs.list.refreshSuccess({ list: this.aroundPOI, total: res.count });
                        });
                    } else {
                        uni.showToast({
                            icon: 'error',
                            title: res.message
                        });
                        this.$refs.list.loadFail();
                    }
                });
            // #endif
            // #ifndef H5
            this.qqmapsdk.getSuggestion({
                keyword: this.searchKeywords || this.keywords,
                page_size: paging.size,
                page_index: paging.page,
                location: `${this.latitude},${this.longitude}`,
                success: res => {
                    if (res.status === 0) {
                        let list = res.data || [];
                        this.handleComputeDistance(list, result => {
                            if (result && result.elements.length) {
                                result.elements.forEach((item, index) => {
                                    list[index].distance = item.distance;
                                });
                            }
                            this.aroundPOI = list;
                            this.$refs.list.refreshSuccess({ list: this.aroundPOI, total: res.count });
                        });
                    } else {
                        uni.showToast({
                            icon: 'error',
                            title: res.message
                        });
                        this.$refs.list.loadFail();
                    }
                },
                fail: res => {
                    uni.showToast({
                        icon: 'error',
                        title: res.message
                    });
                    this.$refs.list.loadFail();
                }
            });
            // #endif
        },
        // 选择地址(需要再次解析)
        handleSelectAddress(address) {
            // #ifdef H5
            this.$request
                .jsonp('https://apis.map.qq.com/ws/geocoder/v1/', {
                    key: this.key,
                    get_poi: 0,
                    output: 'jsonp',
                    callback: 'QQmap',
                    location: `${address.location.lat},${address.location.lng}`
                })
                .then(res => {
                    if (res.status === 0) {
                        uni.$emit(this.eventName, {
                            ...address,
                            town: res.result.address_reference.town
                        });
                        uni.navigateBack();
                    }
                });
            // #endif
            // #ifndef H5
            this.qqmapsdk.reverseGeocoder({
                location: `${address.location.lat},${address.location.lng}`,
                success: res => {
                    if (res.status === 0) {
                        uni.$emit(this.eventName, {
                            ...address,
                            town: res.result.address_reference.town
                        });
                        uni.navigateBack();
                    }
                },
                fail: err => {
                    console.log(err);
                }
            });
            // #endif
        },
        // 返回上个页面
        handleBack() {
            uni.navigateBack();
        }
    },
    filters: {
        getDistance(distance, _distance) {
            distance = distance || _distance;
            let result = '';
            if (distance < 1000) {
                result = distance + 'm';
            } else {
                result = (distance / 1000).toFixed(2) + 'km';
            }
            return result;
        }
    },
    onLoad(option) {
        this.handleInit(option);
    },
    onReady() {
        this.mapCtx = uni.createMapContext('map', this);
        // #ifdef APP-PLUS
        this.mapObj = this.mapCtx.$getAppMap();
        this.mapObj.onstatuschanged = e => {
            // 地图发生变化的时候，获取中间点，也就是cover-image指定的位置
            if (this.longitude != 114.010857) {
                this.mapCtx.getCenterLocation({
                    type: 'gcj02',
                    success: res => {
                        this.handleGeocoder(res.latitude, res.longitude, true);
                    }
                });
            }
        };
        // #endif
    }
};
</script>

<style scoped lang="scss">
.page-wrap {
    .map {
        width: 100%;
        height: 600rpx;
    }
    .back-button {
        /* #ifdef H5 */
        top: 30rpx;
        /* #endif */
        /* #ifndef H5 */
        top: 60rpx;
        /* #endif */
        left: 30rpx;
        width: 60rpx;
        height: 60rpx;
        position: fixed;
    }
    .location-marker {
        left: 50%;
        top: 300rpx;
        width: 60rpx;
        height: 60rpx;
        z-index: 10;
        position: fixed;
        margin-top: -60rpx;
        margin-left: -30rpx;
        &--beat {
            animation: beat 0.4s linear;
        }
    }
    .location-button {
        top: 470rpx;
        right: 40rpx;
        width: 76rpx;
        height: 76rpx;
        z-index: 10;
        border-radius: 50%;
        position: fixed;
        box-shadow: 0 15rpx 10rpx -15rpx #bbb;
    }
    .search-wrap {
        padding: 20rpx 30rpx;
    }
    .address-list {
        .address-item {
            display: flex;
            padding: 20rpx 30rpx;
            align-items: center;
            border-bottom: 1rpx solid #f5f5f5;
            transition: background-color 0.3s ease;
            &--active {
                background-color: #e5e5e5;
            }
            .icon-wrap {
                display: flex;
                flex-shrink: 0;
                margin-right: 20rpx;
            }
            .address-info {
                flex: 1;
                display: flex;
                flex-direction: column;
                .address-name {
                    font-size: 26rpx;
                }
                .address-info-bottom {
                    display: flex;
                    margin-top: 5rpx;
                    align-items: center;
                    .distance-text {
                        color: $primary-color;
                        font-size: 24rpx;
                        margin-right: 10rpx;
                    }
                    .address-text {
                        opacity: 0.5;
                        font-size: 24rpx;
                        overflow: hidden;
                        text-overflow: ellipsis;
                        display: -webkit-box;
                        -webkit-box-orient: vertical;
                        -webkit-line-clamp: 1;
                    }
                }
            }
        }
    }
    @-webkit-keyframes beat {
        0% {
            transform: translateY(0);
        }
        50% {
            transform: translateY(-50rpx);
        }
        100% {
            transform: translateY(0);
        }
    }
}
</style>
